home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- #
- # AFP.c : this module contains the functions used to :
- # - log on an AppleShare server (username/password or guest)
- # - get the number of volumes and their list
- # - get the list of directories with their access rights.
- # - get the server time
- #
- # Once you have logged on, a session is open, it's up to you to logout.
- # Once you have open a volume, you have to close it.
- #
- #
- # Versions: 1.0 10/91
- # Built with MPW 3.2
- #
- # C.Buttin - Apple Computer Europe
- #
- ------------------------------------------------------------------------------*/
-
- #include <Limits.h>
- #include <Types.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <OSUtils.h>
- #include <stdIO.h>
- #include <String.h>
- #include <Strings.h>
- #include <Devices.h>
- #include <OSUtils.h>
- #include <errors.h>
- #include <AppleTalk.h>
-
- /* defined used for AppleTalk */
- #define sync false /* synchronous operation */
- #define quantumSize 578 /* ATP packet size */
- #define countOffset 4
-
- /* structures used by GetDirectories */
- typedef struct OffSpringParam {
- Byte length;
- Byte flags;
- short offsetName;
- long dirID;
- Byte UAM[4];
- }OffSpringParam;
-
- typedef OffSpringParam *OffSpringPtr;
-
- typedef struct InfoDir {
- short UAM; /* access right for this directory */
- long dirID;
- Str32 dirName;
- }InfoDir;
-
- typedef InfoDir *InfoDirPtr;
-
-
- /* C routines declaration. */
- /* InitXPP : Open the ATP and XPP drivers
- Output : noErr or the error number if an error occurred */
- pascal OSErr InitXPP(void);
-
- /* AFP Calls */
- /* GetServerInfo : Get in the reply buffer, information about the server :
- - name
- - machine type
- - UAMs
- lnput : AppleTalk server address
- Pointer on a reply buffer
- length of this buffer
- Output : noErr or the error number if an error occurred */
- pascal OSErr GetServerInfo(AddrBlock *serverAddress,Ptr replyBuffer,short buffLength);
-
- /* LogOnwithName :
- lnput : AppleTalk address of the server
- UserName
- Password
- Pointer on a SCCBlock, must be of size scbMemSize, must remain valid
- and locked during the whole session (i.e. till LogOut)
- Output : session number or the error number if an error occurred */
- pascal short LogOnwithName(AddrBlock *serverAddress,Ptr theName,Ptr thePassword,Ptr SCBBlock);
-
- /* LogOnAsGuest :
- lnput : AppleTalk address of the server
- Pointer on a SCCBlock, must be of size scbMemSize, must remain valid
- and locked during the whole session (i.e. till LogOut)
- Output : session number or the error number if an error occurred */
- pascal short LogOnAsGuest(AddrBlock *serverAddress,Ptr SCBBlock);
-
- /* GetServerParams : Get in the reply buffer,the number of volumes
- and the volume list
- lnput : Session Reference Number
- Pointer on a reply buffer
- length of this buffer
- Output : noErr or the error number if an error occurred */
- pascal OSErr GetServerParams(short sessNum,Ptr replyBuffer,short buffLength);
-
- /* OpenVolume : Open an AppleShare volume
- lnput : Session Reference Number
- volume name
- Output : volume number
- error number if an error occurred */
- pascal short OpenVolume(short sessNum,Ptr volumeName,short* volID);
-
- /* GetVolumePrivileges : Returns the privileges of the volume.
- lnput : Session Reference Number
- volume ID
- Output : volume privileges or error number if an error occurred */
- pascal short GetVolumePrivileges(short sessionNum,short volumeID);
-
- /* GetDirectories : Returns in a buffer the list of directories :
- name (pascal string)
- dirID
- access mode
- lnput : Session Reference Number
- volume ID
- directory to be listed
- buffer to receive the data
- length of this buffer
- max number of dirs to be got
- Output : error number if an error occurred */
- pascal OSErr GetDirectories(short sessNum,short volID,long dirID,
- Ptr buffer,short buffLength,short reqCount);
-
- /* CloseVolume : Close an AppleShare volume
- lnput : Volume Reference Number */
- pascal void CloseVolume(short sessNum,short volumeID);
-
- /* LogOut : stop the session
- lnput : Session Reference Number
- Pointer SCBBlock
- Output : noErr or the error number if an error occurred */
- pascal OSErr LogOut(short sessNum,Ptr SCBBlock);
-
- /* Server utilities */
- /* CheckUAM : verify if a User Access Method is available
- Input : string containing the method name
- reply buffer got from GetServerInfo
- Output : Boolean, true is the method is available */
- pascal Boolean CheckUAM(const Str32 theMethod,Ptr replyBuffer);
-
- /* GetServerTime : extract the server time from the reply
- got from GetServerParams
- Input : reply buffer
- Output : server time (in seconds, on Macintosh Unit (since Januray 1904) */
- pascal unsigned long GetServerTime(Ptr replyBuffer);
-
- /* Volumes utilities */
- /* GetNumberVolumes : extract the number of volumes of the server
- from the reply got from GetServerParams
- Input : reply buffer
- Output : number of volumes */
- pascal short GetNumberVolumes(Ptr replyBuffer);
-
- /* ExtractVolumeName : extract the nth volume from the reply buffer
- got from GetServerParams
- Input : reply buffer
- volumeNumber
- empty string to receive the volume name (as a Pascal string)
- Output : Boolean, false if volume number is too big */
- pascal Boolean ExtractVolumeName(Ptr replyBuffer,short volumeNumber,Str255 theVol);
-
-
- /* Directories utilities */
- /* GetNumberDirs : extract the number of directories from the reply got
- from GetDirectories
- Input : reply buffer
- Output : number of Dirs */
- pascal short GetNumberDirs(Ptr replyBuffer);
-
- /* ExtractDirInfo : extract the info regarding the nth dir from the reply buffer
- got from GetDirectories
- Input : reply buffer
- dirNumber
- Pointer on a dirInfo structure
- Output : Boolean, false if dirNumber is too big */
- pascal Boolean ExtractDirInfo(Ptr replyBuffer,short dirNumber,InfoDirPtr theDir);
-
-
- /**** CODE ****/
-
- pascal OSErr InitXPP(void)
- {
- short drivernum;
- OSErr error;
-
- /* open .ATP driver and .XPP driver */
- if ((error = ATPLoad()) != noErr)
- return error;
- /* open .XPP driver */
- return OpenXPP(&drivernum);
- } /* InitXPP */
-
-
- /* AFP functions */
-
- pascal OSErr GetServerInfo(AddrBlock *serverAddress,Ptr replyBuffer,short buffLength)
- {
- XPPParamBlock *XPPBlock; /* to build parameter blocks for AFP */
- OSErr error;
-
- if ((error = InitXPP()) != noErr)
- return error;
-
- if (!(XPPBlock = (XPPParamBlock *)NewPtrClear(sizeof(XPPParamBlock))))
- return MemError();
-
- XPPBlock->XPP.ioRefNum = xppRefNum; /* driver reference number */
- /* prepare command information :
- no input provided except command - see IA 13-95.
- In the Mac inplementation you must use ASPGetStatus (see IM vol.V-541) */
- XPPBlock->OPEN.serverAddr = *serverAddress; /* AppleTalk address of the server */
- XPPBlock->XPP.aspTimeout = 2; /* Timeout for ATP */
- XPPBlock->XPP.aspRetry = 2;
- XPPBlock->XPP.rbPtr = replyBuffer; /* Reply buffer pointer */
- XPPBlock->XPP.rbSize = buffLength;
-
- error = ASPGetStatus((XPPParmBlkPtr)XPPBlock,sync);
- DisposPtr((Ptr)XPPBlock);
- return error;
-
- } /* GetServerInfo */
-
- /* Log on server */
- pascal short LogOnwithName(AddrBlock *serverAddress,Ptr theName,Ptr thePassword,Ptr SCBBlock)
- {
- AFPLoginPrm *XPPBlock; /* to build parameter blocks for AFP */
- short i,lgInfo,cbsize;
- char XPPReply[quantumSize*8]; /* used to get AFP replies (max. size 8 ATP packet) */
- char XPPCmd[quantumSize]; /* used to send AFP commands */
- OSErr error;
- short result;
- char userAuthInfo[50];
-
- /* information used by Login function */
- char AFPVersion[30];
- char AuthentMethod[30];
-
- strcpy(AFPVersion, "\pAFPVersion 2.0");
- strcpy(AuthentMethod, "\pCleartxt passwrd");
- /* prepare user info */
- lgInfo = (short)theName[0]+1;
- BlockMove(theName,userAuthInfo,lgInfo);
- if (lgInfo % 2 == 0) {
- /* pad with a null byte to have password on even boundary */
- lgInfo++;
- userAuthInfo[lgInfo] = '\0';
- }
- for (i = 1; i <= thePassword[0]; i++,lgInfo++)
- userAuthInfo[lgInfo] = thePassword[i];
- for (; i <= 8; i++,lgInfo++) /* pad with null bytes if necessary */
- userAuthInfo[lgInfo] = '\0';
-
- if (!(XPPBlock = (AFPLoginPrm *)NewPtrClear(sizeof(AFPLoginPrm))))
- return MemError();
-
- XPPBlock->ioRefNum = xppRefNum;
- XPPBlock->ioCompletion = nil;
- XPPBlock->aspTimeout = 1; /* Timeout for ATP */
- XPPBlock->aspRetry = 2; /* Retry count for ATP */
- XPPBlock->afpAddrBlock = *serverAddress; /* AppleTalk address of the server */
- XPPBlock->afpAttnRoutine = nil ;
- XPPBlock->rbPtr = (Ptr)XPPReply; /* Reply buffer pointer */
- XPPBlock->rbSize = quantumSize; /* Reply buffer size */
-
- /* prepare command information :
- 1st byte : command (login)
- 2nd Pascal string : AFP version
- 3rd Pascal string : Authentication Method - see Inside AppleTalk 13-105
- 4th user information : username - password */
- XPPCmd[0] = afpLogin;
- cbsize = 1;
- BlockMove(AFPVersion,XPPCmd+cbsize,AFPVersion[0]+1);
- cbsize += AFPVersion[0]+1;
- BlockMove(AuthentMethod,XPPCmd+cbsize,AuthentMethod[0]+1);
- cbsize += AuthentMethod[0]+1;
-
- /* add user info */
- BlockMove(userAuthInfo,XPPCmd+cbsize,lgInfo);
- cbsize += lgInfo;
-
- XPPBlock->cbPtr = (Ptr)XPPCmd; /* Command block pointer */
- XPPBlock->cbSize = cbsize;
- XPPBlock->afpSCBPtr = (Ptr) SCBBlock; /* SCB pointer in AFP login */
-
- if ((error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync)) != noErr)
- result = error;
- else
- if (XPPBlock->cmdResult != noErr)
- result = XPPBlock->cmdResult ;
- else result = XPPBlock->sessRefnum; /* return session number */
-
- DisposPtr((Ptr)XPPBlock);
- return result;
- } /* LogOnwithName */
-
- pascal short LogOnAsGuest(AddrBlock *serverAddress,Ptr SCBBlock)
- {
- AFPLoginPrm *XPPBlock; /* to build parameter blocks for AFP */
- short cbsize;
- char XPPReply[quantumSize*8]; /* used to get AFP replies (max. size 8 ATP packet) */
- char XPPCmd[quantumSize]; /* used to send AFP commands */
- OSErr error;
- short result;
- /* information used by Login function */
- char AFPVersion[30];
- char AuthentMethod[30];
-
- strcpy(AFPVersion, "AFPVersion 2.0");
- strcpy(AuthentMethod, "No User Authent");
-
- if (!(XPPBlock = (AFPLoginPrm *)NewPtrClear(sizeof(AFPLoginPrm))))
- return MemError();
-
- XPPBlock->ioRefNum = xppRefNum;
- XPPBlock->ioCompletion = nil;
- XPPBlock->aspTimeout = 1; /* Timeout for ATP */
- XPPBlock->aspRetry = 2; /* Retry count for ATP */
- XPPBlock->afpAddrBlock = *serverAddress; /* AppleTalk address of the server */
- XPPBlock->afpAttnRoutine = nil ;
- XPPBlock->rbPtr = (Ptr)XPPReply; /* Reply buffer pointer */
- XPPBlock->rbSize = quantumSize; /* Reply buffer size */
-
- /* prepare command information :
- 1st byte : command (login)
- 2nd Pascal string : AFP version
- 3rd Pascal string : Authentication Method - see Inside AppleTalk 13-104 */
- XPPCmd[0] = afpLogin;
- XPPCmd[1] = strlen(AFPVersion);
- strcpy(XPPCmd+2,AFPVersion);
- cbsize = strlen(XPPCmd);
- XPPCmd[cbsize] = strlen(AuthentMethod);
- strcpy(XPPCmd+cbsize+1,AuthentMethod);
- cbsize = strlen(XPPCmd);
-
- XPPBlock->cbPtr = (Ptr)XPPCmd; /* Command block pointer */
- XPPBlock->cbSize = cbsize;
- XPPBlock->afpSCBPtr = (Ptr) SCBBlock; /* SCB pointer in AFP login */
-
- if ((error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync)) != noErr)
- result = error;
- else
- if (XPPBlock->cmdResult != noErr)
- result = XPPBlock->cmdResult ;
- else result = XPPBlock->sessRefnum; /* return session number */
-
- DisposPtr((Ptr)XPPBlock);
- return result;
- } /* LogOnAsGuest */
-
- /* get the server parameters (AFP call : GetSrvParms) */
- pascal OSErr GetServerParams(short sessNum,Ptr replyBuffer,short buffLength)
- {
- XPPPrmBlk *XPPBlock; /* to build parameter blocks for AFP */
- char XPPCmd[quantumSize]; /* used to send AFP commands */
- OSErr error;
-
- if (!(XPPBlock = (XPPPrmBlk *)NewPtrClear(sizeof(XPPPrmBlk))))
- return MemError();
-
- XPPBlock->ioRefNum = xppRefNum; /* driver reference number */
- /* prepare command information :
- no input provided except command - see IA 13-98 */
- XPPCmd[0] = afpGetSParms;
-
- XPPBlock->sessRefnum = sessNum;
- XPPBlock->aspTimeout = 2; /* Timeout for ATP */
- XPPBlock->aspRetry = 2;
- XPPBlock->cbPtr = (Ptr)XPPCmd;
- XPPBlock->cbSize = 1; /* Command block size */
- XPPBlock->rbPtr = replyBuffer; /* Reply buffer pointer */
- XPPBlock->rbSize = buffLength;
- XPPBlock->wdSize = 0; /* Write Data size */
- XPPBlock->wdPtr = nil; /* Write Data pointer */
-
- error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync);
- DisposPtr((Ptr)XPPBlock);
- return error;
- }
-
- /* Open an AppleShare volume */
- pascal OSErr OpenVolume(short sessNum,Ptr volumeName,short* volID)
- {
-
- XPPPrmBlk *XPPBlock; /* to build parameter blocks for AFP */
- char XPPCmd[quantumSize]; /* used to send AFP commands */
- OSErr error;
- char replyBuffer[100];
-
- if (!(XPPBlock = (XPPPrmBlk *)NewPtrClear(sizeof(XPPPrmBlk))))
- return MemError();
-
- XPPBlock->ioRefNum = xppRefNum; /* driver reference number */
- /* prepare command information :
- command
- bitmap
- volume name as a pascal string - see IA 13-121 */
- XPPCmd[0] = afpOpenVol;
- XPPCmd[1] = 0;
- XPPCmd[2] = 0;
- XPPCmd[3] = 0x20; /* we just want the volume ID (bit 5 in bitmap) */
- BlockMove(volumeName,XPPCmd+4,volumeName[0]+1);
-
- XPPBlock->sessRefnum = sessNum;
- XPPBlock->aspTimeout = 2; /* Timeout for ATP */
- XPPBlock->aspRetry = 2;
- XPPBlock->cbPtr = (Ptr)XPPCmd;
- XPPBlock->cbSize = volumeName[0]+5; /* Command block size */
- XPPBlock->rbPtr = replyBuffer; /* Reply buffer pointer */
- XPPBlock->rbSize = 100;
- XPPBlock->wdSize = 0; /* Write Data size */
- XPPBlock->wdPtr = nil; /* Write Data pointer */
-
- if ((error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync)) == noErr)
- if (XPPBlock->cmdResult != noErr)
- error = XPPBlock->cmdResult ;
- else {
- /* volume parameters are contained within the reply buffer
- the volume ID is at byte 2 and it's two bytes long
- (see Inside AppleTalk pp 13-102 && 13-121 */
- BlockMove(replyBuffer+ 2,volID,2); /* return volume number */
- }
- if (error)
- *volID = -1;
-
- DisposPtr((Ptr)XPPBlock);
- return error;
- } /* OpenVolume */
-
- /* getting the volume privileges is the same as getting the root privileges */
- pascal short GetVolumePrivileges(short sessionNum,short volumeID)
- {
-
-
- XPPPrmBlk *XPPBlock; /* to build parameter blocks for AFP */
- char XPPCmd[quantumSize]; /* used to send AFP commands */
- OSErr error;
- short lg;
- Byte buffer[100];
- long dirID = 2; /* the root has the dirID 2 */
- Byte UAM[4];
-
- if (!(XPPBlock = (XPPPrmBlk *)NewPtrClear(sizeof(XPPPrmBlk))))
- return MemError();
-
- XPPBlock->ioRefNum = xppRefNum; /* driver reference number */
- /* prepare command information :
- command : FPGetFileDirParms see IA - 13-83
- 0
- volumeID
- DirectoryID of the directory we are looking for
- File BitMap not used
- Directory BitMap
- PathType
- PathName not used (must be set to empty string) */
-
- lg = 0;
- XPPCmd[lg++] = afpGetFlDrParms;
- XPPCmd[lg++] = 0;
- BlockMove(&volumeID,XPPCmd+lg,2); /* volumeID */
- lg += 2;
- BlockMove(&dirID,XPPCmd+lg,4); /* dirID */
- lg += 4;
- XPPCmd[lg++] = 0; /* File BitMap */
- XPPCmd[lg++] = 0; /* File BitMap */
- XPPCmd[lg++] = 0x10; /* Directory BitMap : Access Rights */
- XPPCmd[lg++] = 0; /* Directory BitMap */
- XPPCmd[lg++] = 2; /* pathname is long name */
- XPPCmd[lg++] = '\0'; /* pathname is empty */
-
- XPPBlock->sessRefnum = sessionNum;
- XPPBlock->aspTimeout = 2; /* Timeout for ATP */
- XPPBlock->aspRetry = 2;
- XPPBlock->cbPtr = (Ptr)XPPCmd;
- XPPBlock->cbSize = lg; /* Command block size */
- XPPBlock->rbPtr = buffer; /* Reply buffer pointer */
- XPPBlock->rbSize = 100;
- XPPBlock->wdSize = 0; /* Write Data size */
- XPPBlock->wdPtr = nil; /* Write Data pointer */
-
- if ((error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync)) == noErr)
- if (XPPBlock->cmdResult != noErr)
- error = XPPBlock->cmdResult ;
- /* the access rights are set up after the file and dir bitmaps
- + 2 bytes of flags */
- BlockMove(buffer + 6,UAM,4);
- /* return the first octet as a short */
- lg = (short)UAM[0];
- DisposPtr((Ptr)XPPBlock);
- return ((error == noErr) ? lg : error);
-
- } /* GetVolumePrivileges */
-
- /* Get the list of subdirectories of a directory with their name,
- dirID and privileges */
- pascal OSErr GetDirectories(short sessNum,short volID,long dirID,
- Ptr buffer,short buffLength,short reqCount)
- {
-
- XPPPrmBlk *XPPBlock; /* to build parameter blocks for AFP */
- char XPPCmd[quantumSize]; /* used to send AFP commands */
- OSErr error;
- short temp,lg;
-
- if (!(XPPBlock = (XPPPrmBlk *)NewPtrClear(sizeof(XPPPrmBlk))))
- return MemError();
- /* we expect to receive as reply, for each dir in the directory :
- - the offset to dirname (short)
- - the dirID (long)
- - the Access rights of the dir (long)
- - the name of the dir (Str32) */
- if ((reqCount * 50) > buffLength)
- return afpParmErr; /* buffer too small */
-
- XPPBlock->ioRefNum = xppRefNum; /* driver reference number */
- /* prepare command information :
- command : FPEnumerate see IA 13-73
- 0
- volumeID
- DirectoryID to be browsed
- File BitMap not used
- Directory BitMap dirName + dirID + access rights
- ReqCount
- StartIndex
- MaxReplySize
- PathType
- PathName not used (must be set to empty string) */
- lg = 0;
- XPPCmd[lg++] = afpEnumerate;
- XPPCmd[lg++] = 0;
- BlockMove(&volID,XPPCmd+lg,2); /* volumeID */
- lg += 2;
- BlockMove(&dirID,XPPCmd+lg,4); /* parID */
- lg += 4;
- XPPCmd[lg++] = 0; /* File BitMap */
- XPPCmd[lg++] = 0; /* File BitMap */
- XPPCmd[lg++] = 0x11; /* Directory BitMap : Access Rights + dirID */
- XPPCmd[lg++] = 0x40; /* Directory BitMap : names */
- BlockMove(&reqCount,XPPCmd+lg,2); /* requested count */
- lg += 2;
- temp = 1; /* start index */
- BlockMove(&temp,XPPCmd+lg,2);
- lg += 2;
- temp = reqCount * 50; /* maximum size of reply block */
- BlockMove(&temp,XPPCmd+lg,2);
- lg += 2;
- XPPCmd[lg++] = 2; /* pathname is long name */
- XPPCmd[lg++] = '\0'; /* pathname is empty */
-
- XPPBlock->sessRefnum = sessNum;
- XPPBlock->aspTimeout = 2; /* Timeout for ATP */
- XPPBlock->aspRetry = 2;
- XPPBlock->cbPtr = (Ptr)XPPCmd;
- XPPBlock->cbSize = lg; /* Command block size */
- XPPBlock->rbPtr = buffer; /* Reply buffer pointer */
- XPPBlock->rbSize = buffLength;
- XPPBlock->wdSize = 0; /* Write Data size */
- XPPBlock->wdPtr = nil; /* Write Data pointer */
-
- if ((error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync)) == noErr)
- if (XPPBlock->cmdResult != noErr)
- error = XPPBlock->cmdResult ;
- DisposPtr((Ptr)XPPBlock);
- return error;
- } /* GetDirectories */
-
- /* close an AppleShare volume */
- pascal void CloseVolume(short sessNum,short volumeID)
- {
-
-
- XPPPrmBlk *XPPBlock; /* to build parameter blocks for AFP */
- char XPPCmd[quantumSize]; /* used to send AFP commands */
- OSErr error;
-
- if (!(XPPBlock = (XPPPrmBlk *)NewPtrClear(sizeof(XPPPrmBlk))))
- return ;
-
- XPPBlock->ioRefNum = xppRefNum; /* driver reference number */
- /* prepare command information :
- command 1 byte
- 0 1 byte
- volumeID 2 bytes see IA 13-63 */
- XPPCmd[0] = afpVolClose;
- XPPCmd[1] = 0;
- BlockMove(&volumeID,XPPCmd+2,2);
-
- XPPBlock->sessRefnum = sessNum;
- XPPBlock->aspTimeout = 2; /* Timeout for ATP */
- XPPBlock->aspRetry = 2;
- XPPBlock->cbPtr = (Ptr)XPPCmd;
- XPPBlock->cbSize = 4; /* Command block size */
- XPPBlock->rbPtr = nil; /* Reply buffer pointer */
- XPPBlock->rbSize = 0;
- XPPBlock->wdSize = 0; /* Write Data size */
- XPPBlock->wdPtr = nil; /* Write Data pointer */
-
- error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync);
- DisposPtr((Ptr)XPPBlock);
- }
- /* CloseVolume */
-
- /* Close the session */
- pascal OSErr LogOut(short sessNum,Ptr SCBBlock)
- {
- #pragma unused (SCBBlock)
-
- XPPPrmBlk *XPPBlock; /* to build parameter blocks for AFP */
- char XPPCmd[quantumSize]; /* used to send AFP commands */
- OSErr error;
-
- if (!(XPPBlock = (XPPPrmBlk *)NewPtrClear(sizeof(XPPPrmBlk))))
- return MemError();
- XPPBlock->ioRefNum = xppRefNum; /* driver reference number */
- /* prepare command information :
- just the command see IA 13-108 */
- XPPCmd[0] = afpLogout;
- XPPBlock->cbPtr = (Ptr)XPPCmd; /*Command block pointer */
- XPPBlock->cbSize = 1;
-
- XPPBlock->sessRefnum = sessNum;
- XPPBlock->aspTimeout = 2; /*Timeout for ATP */
- XPPBlock->aspRetry = 2;
-
- error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync);
- DisposPtr((Ptr)XPPBlock);
- return error;
-
- } /* LogOut */
-
-
- /*** UTILITIES ***/
-
-
- /* Check if a UAM is available */
- pascal Boolean CheckUAM(const Str32 theMethod,Ptr replyBuffer)
- {
- short offset,i,j,numUAMs,length;
- Ptr p;
-
- BlockMove(replyBuffer+4, &offset,2); /* to get the offset of UAMs in the buffer */
- numUAMs = (short)(*(replyBuffer + offset));
- /* UAMs are packed as Pascal string. By comparing the strings,
- we can see if find the right UAM */
- p = replyBuffer + offset + 1;
- for (i = 1, length = (short)*p; i <= numUAMs ;i++) {
- for (j = 1; j <= length;j++)
- if (theMethod[j] != p[j])
- break;
- if (j > length) /* we found it */
- return true;
- else
- if (i < numUAMs) {
- p += length+1;
- length = (short)*p;
- }
- }
- return false;
- } /* CheckUAM */
-
- /* calculate the server time in seconds in Macintosh units */
- pascal unsigned long GetServerTime(Ptr replyBuffer)
- {
- long theTime,theLocalTime;
- DateTimeRec theDate;
-
- /* the Volumes buffer contains : see IA p 13-99
- - server time (long) : this value is the number of seconds
- measured from 12:00 am on Januray 1,2000 */
-
- BlockMove(replyBuffer,&theTime,4);
- /* calculate the number of seconds till Januray 1, 2000 */
- theDate.day = 1;
- theDate.month = 1;
- theDate.year = 2000;
- theDate.hour = 0;
- theDate.minute = 0;
- theDate.second = 0;
- Date2Secs(&theDate,(unsigned long* )&theLocalTime);
- /* add the two values to get the right time */
- theTime += theLocalTime;
- return theTime;
-
- } /* GetServerTime */
-
- /* Get the number of volumes of an AppleShare server */
- pascal short GetNumberVolumes(Ptr replyBuffer)
- {
- short numVol;
-
- /* the Volumes buffer contains : see IA p 13-99
- - server time (long)
- - num of vols. (short) */
-
- numVol = (short)*(replyBuffer+4);
- return numVol;
-
- } /* GetNumberVolumes */
-
- /* extract from the AFP reply buffer a volume name as a pascal string */
- pascal Boolean ExtractVolumeName(Ptr replyBuffer,short volumeNumber,char *theVol)
- {
- /* the structure of the buffer is defined as follow (see Inside AppleTalk
- p 13-98) :
- 1 byte for flags (volume has password )
- Volume name as a Pascal string. Volume names are delimited by a null char
- if even number of chars.*/
-
- short i,j,length;
-
- if (volumeNumber > GetNumberVolumes(replyBuffer))
- return false;
- replyBuffer = replyBuffer+5; /* position at 1st volume name */
- for (i = 1; i <= volumeNumber;i++) {
- length = (short)(*(++replyBuffer)); /* skeep flag byte */
- for (j = 0; j <= length;j++,replyBuffer++) /* volume Name */
- if (i == volumeNumber)
- theVol[j] = *replyBuffer;
- }
- return true;
- } /* ExtractVolumeName */
-
-
- /* Directories utilities */
- /* Get the number of subdirectories of a directory */
- pascal short GetNumberDirs(Ptr replyBuffer)
- {
- short count;
-
- /* the GetDirectories buffer contains : see IA p 13-76
- - file BitMap (short)
- - dirBitMap (short)
- - count (short) */
-
- BlockMove(replyBuffer+4,&count,2);
- return count;
- } /* GetNumberDirs */
-
- /* Get the name, dirID and access rights of a directory */
- pascal Boolean ExtractDirInfo(Ptr p,short dirNumber,InfoDirPtr theDir)
- {
- short i,length;
-
- /* verify if dirNumber is OK */
- if (dirNumber > GetNumberDirs(p))
- return false;
- /* skip countInfo in the buffer */
- p += 6;
-
- for (i = 1; i < dirNumber;i++) /* skip first dirs */
- p = p+((OffSpringPtr)p)->length;
-
- /* we expect to receive in reply, for each directory :
- - the offset to dirname
- - the dirID (long)
- - the Access rights of the dir (long)
- - the name of the dir (Str32) see IA 13-74 */
-
- theDir->UAM = (short)(((OffSpringPtr)p)->UAM[0]);
- theDir->dirID = ((OffSpringPtr)p)->dirID;
-
-
- /* skip first bytes (lenght,flags) */
- length = ((OffSpringPtr)p)->offsetName + 2;
- p += length;
- BlockMove(p,theDir->dirName,*p+1);
- return true;
- } /* ExtractDirInfo */
-